
typedef unsigned int   uint;

void ForwardCycle(uint *pN1, uint *pN2);
void BackCycle(uint *pN1, uint *pN2);

void MainStep(uint *pN1, uint *pN2, uint X);
uint TablChanging(uint valIn);
void swap(uint *pA, uint *pB);

uint const TabSub[16]=  { 0xFFFFFFFF,
                          0xEEEEEEEE,
                          0xDDDDDDDD,
                          0xCCCCCCCC,
                          0xBBBBBBBB,
                          0xAAAAAAAA,
                          0x99999999,
                          0x88888888,
                          0x77777777,
                          0x66666666,
                          0x55555555,
                          0x44444444,
                          0x33333333,
                          0x22222222,
                          0x11111111,
                          0x00000000  };

uint const Key[8]=  { 0x12345678,
                      0x9ABCDEF0,
                      0x0FEDCBA9,
                      0x87654321,
                      0x01234567,
                      0x89ABCDEF,
                      0x0FE67899,
                      0x7847374D  };



void EncryptionCycle(uint *pBhi, uint *pAlo)
{ 
  ForwardCycle(pAlo,pBhi); ForwardCycle(pAlo,pBhi); ForwardCycle(pAlo,pBhi); BackCycle(pAlo,pBhi);
  swap(pAlo,pBhi);
}

void DecryptionCycle(uint *pBhi, uint *pAlo)
{ 
  ForwardCycle(pAlo,pBhi); BackCycle(pAlo,pBhi); BackCycle(pAlo,pBhi); BackCycle(pAlo,pBhi);
  swap(pAlo,pBhi);
}

void AuthenticationCycle(uint *pN1, uint *pN2)
{ ForwardCycle(pN1,pN2); ForwardCycle(pN1,pN2); ForwardCycle(pN1,pN2); BackCycle(pN1,pN2); }





void ForwardCycle(uint *pN1, uint *pN2)
{ int cycle;
  for(cycle=0; cycle<8; ++cycle) {MainStep(pN1,pN2,Key[cycle]);}
}

void BackCycle(uint *pN1, uint *pN2)
{ int cycle;
  for(cycle=7; cycle>-1; --cycle) {MainStep(pN1,pN2,Key[cycle]);}
}


void MainStep(uint *pN1, uint *pN2, uint X)
{ uint S;
//
  S = TablChanging(*pN1 + X);   S = ((S<<11)|(S>>21))^*pN2;
  *pN2 = *pN1;    *pN1 = S; 
}





uint TablChanging(uint valIn)
{  uint cycle, valOut=0, msk = 0x0000000F;
//
  for(cycle=0; cycle<8; ++cycle)
   { valOut |= TabSub[(valIn&msk)>>cycle*4]&msk;  msk <<= 4; }
//
  return valOut;
}


void swap(uint *pA, uint *pB)   { uint C = *pA; *pA = *pB; *pB = C; }